home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Server⁄Tracker 4.0 / notes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-01  |  3.5 KB  |  165 lines  |  [TEXT/KAHL]

  1. /* notes.c */
  2.  
  3. /* $Id: notes.c,v 4.0 1994/01/11 17:50:04 espie Exp espie $
  4.  * $Log: notes.c,v $
  5.  * Revision 4.0  1994/01/11  17:50:04  espie
  6.  * Makes use of autoinit. Uses less memory, starts up faster.
  7.  *
  8.  * Revision 1.6  1994/01/09  17:36:22  Espie
  9.  * Generalized open.c.
  10.  *
  11.  * Revision 1.5  1994/01/08  03:55:43  Espie
  12.  * auto_init'd create_notes_table(),
  13.  * suppressed note_name static table,
  14.  * use name_of_note() instead (about 120 * 8 bytes gain).
  15.  *
  16.  * Revision 1.4  1994/01/05  16:10:49  Espie
  17.  * *** empty log message ***
  18.  *
  19.  * Revision 1.3  1994/01/05  14:54:09  Espie
  20.  * *** empty log message ***
  21.  *
  22.  * Revision 1.2  1994/01/05  13:50:43  Espie
  23.  * Cosmetic change.
  24.  *
  25.  * Revision 1.1  1993/12/26  00:55:53  Espie
  26.  * Initial revision
  27.  *
  28.  * Revision 3.6  1993/12/04  16:12:50  espie
  29.  * New locals
  30.  *
  31.  * Revision 3.5  1993/11/17  15:31:16  espie
  32.  * *** empty log message ***
  33.  *
  34.  * Revision 3.4  1993/11/11  20:00:03  espie
  35.  * Amiga support.
  36.  *
  37.  * Revision 3.2  1992/11/20  14:53:32  espie
  38.  * Added finetune.
  39.  *
  40.  * Revision 3.1  1992/11/19  20:44:47  espie
  41.  * Protracker commands.
  42.  *
  43.  * Revision 3.0  1992/11/18  16:08:05  espie
  44.  * New release.
  45.  *
  46.  */
  47.  
  48. #include "defs.h"
  49.  
  50. #ifdef MALLOC_NOT_IN_STDLIB
  51. #include <malloc.h>
  52. #else
  53. #include <stdlib.h>
  54. #endif
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <ctype.h>
  58. #include <assert.h>
  59. #include <math.h>
  60.  
  61. #include "song.h"
  62. #include "channel.h"
  63. #include "extern.h"
  64.  
  65. ID("$Id: notes.c,v 4.0 1994/01/11 17:50:04 espie Exp espie $")
  66.  
  67.  
  68. /* we can put it autoinit since find_note is ALWAYS called
  69.  * prior to finding note values !
  70.  */
  71. LOCAL void create_notes_table P((void));
  72. LOCAL void (*INIT)P((void)) = create_notes_table;
  73.  
  74.  
  75. /* the musical notes correspond to some specific pitch.
  76.  * It's useful to be able to find them back, at least for
  77.  * arpeggii.
  78.  */
  79. short pitch_table[NUMBER_NOTES][NUMBER_FINETUNES];
  80.  
  81. LOCAL char *note_template = "C-C#D-D#E-F-F#G-G#A-A#B-";
  82.  
  83. /* find_note(pitch): find note corresponding to the stated pitch */
  84. int find_note(pitch)
  85. int pitch;
  86.    {
  87.    int a, b, i;
  88.    
  89.    INIT_ONCE;
  90.  
  91.    if (pitch == 0)
  92.       return -1;
  93.    a = 0;
  94.    b = NUMBER_NOTES-1;
  95.    while(b-a > 1)
  96.       {
  97.       i = (a+b)/2;
  98.       if (pitch_table[i][0] == pitch)
  99.          return i;
  100.       if (pitch_table[i][0] > pitch)
  101.          a = i;
  102.       else
  103.          b = i;
  104.       }
  105.    if (pitch_table[a][0] - FUZZ <= pitch)
  106.       return a;
  107.    if (pitch_table[b][0] + FUZZ >= pitch)
  108.       return b;
  109.    return NO_NOTE;
  110.    }
  111.  
  112. LOCAL void create_notes_table()
  113.    {
  114.    double base, pitch;
  115.    int i, j, k;
  116.  
  117.    for (j = -8; j < 8; j++)
  118.       {
  119.       k = j < 0 ? j + 16 : j;
  120.       base = AMIGA_CLOCKFREQ/440.0/4.0 / pow(2.0, j/96.0);
  121.  
  122.       for (i = 0; i < NUMBER_NOTES; i++)
  123.          {
  124.          pitch = base / pow(2.0, i/12.0);
  125.          pitch_table[i][k] = floor(pitch + 0.5);
  126.          }
  127.       }
  128.     }
  129.  
  130. char *name_of_note(i)
  131. int i;
  132.    {
  133.    static char name[4];
  134.  
  135.    if (i == NO_NOTE)
  136.       return "   ";
  137.    else 
  138.       {
  139.       name[0] = note_template[(i+9)%12 * 2];
  140.       name[1] = note_template[(i+9)%12 * 2 +1];
  141.       name[2] = '0' + (i-3)/12;
  142.       name[3] = 0;
  143.       return name;
  144.       }
  145.    }
  146.    
  147. int transpose_song(s, transpose)
  148. struct song *s;
  149. int transpose;
  150.    {
  151.    int oldt;
  152.    int i, j, n;
  153.  
  154.    if (!s)
  155.       return 0;
  156.    oldt = s->info.transpose;
  157.    for (n = 0; n < s->info.maxpat; n++)
  158.       for (i = 0; i < BLOCK_LENGTH; i++)
  159.          for (j = 0; j < NUMBER_TRACKS; j++)
  160.             if (s->info.pblocks[n].e[j][i].note != NO_NOTE)
  161.                s->info.pblocks[n].e[j][i].note += transpose - oldt;
  162.    s->info.transpose = transpose;
  163.    return oldt;
  164.    }
  165.